﻿using CommonTool;
using GTS;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using Tool;

namespace Motions
{
    class GTSMotion : Motions
    {
        uint _isHomeNow;
        uint _isHomeErr;
        uint _stopHome;
        Mutex _homeMutex = new Mutex();
        public GTSMotion(int nCardIndex, string strName, int nMinAxisNo, int nMaxAxisNo)
             : base(nCardIndex, strName, nMinAxisNo, nMaxAxisNo)
        {
            m_bEnable = false;
        }


        /// <summary>
        /// 轴卡初始化
        /// </summary>
        /// <returns></returns>
        public override void InitMotionCard()
        {
            short rtn = 0;
            rtn += GtsBase.GT_Open((short)m_nCardIndex, 0, 1);//打开控制器
            rtn += GtsBase.GT_Reset((short)m_nCardIndex);//复位控制器
            rtn += GtsBase.GT_LoadConfig((short)m_nCardIndex, AppDomain.CurrentDomain.BaseDirectory + "GTS800.cfg");//加载路径
            if (0 == rtn)
            {
                m_bEnable = true;//初始化成功             
            }
            m_bEnable = false;
            //MessageBox.Show(string.Format("运动控制卡GTS800初始化失败,卡号: {1}, result = {0}", rtn, m_nCardIndex));
            //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("运动控制卡GTS800初始化失败,卡号: {1}, result = {0}", rtn, m_nCardIndex));
        }

        /// <summary>
        /// 关闭轴卡
        /// </summary>
        /// <returns></returns>
        public override void DeInitMotionCard()
        {
            short rtn = 0;
            rtn += GtsBase.GT_Close((short)m_nCardIndex); //关闭轴卡
            if (0 != rtn)
            {
                MessageBox.Show(string.Format("运动控制卡GTS800关闭轴卡失败,卡号: {1}, result = {0}", rtn, m_nCardIndex));
                LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("运动控制卡GTS800关闭轴卡失败,卡号: {1}, result = {0}", rtn, m_nCardIndex));
            }
        }

        /// <summary>
        /// 按位获取输入信号
        /// </summary>
        /// <param name="nIndex">点位号</param>
        /// <returns></returns>
        public override bool ReadIn(int nCardN0, int nIndex)
        {
            int nData = 0;

            if (0 == GtsBase.GT_GetDi((short)m_nCardIndex, GtsBase.MC_GPI, out nData))//卡号 4 通用输入
            {
                return 0 == (nData & (1 << (nIndex - 1))); //信号触发
            }
            //MessageBox.Show(string.Format("第{0}张卡第{1}个获取输入信号失败---- ", m_nCardIndex, nIndex));
            //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个获取输入信号失败 ---- ", m_nCardIndex, nIndex));
            return false;
        }

        /// <summary>
        /// 按位获取输出信号
        /// </summary>
        /// <param name="nIndex">点位号</param>
        /// <returns></returns>
        public override bool ReadOut(int nCardN0, int nIndex)
        {
            int nData = 0;
            if (0 == GtsBase.GT_GetDo((short)m_nCardIndex, GtsBase.MC_GPO, out nData))
            {
                return 0 == (nData & (1 << (nIndex - 1))); //信号触发
            }
            //MessageBox.Show(string.Format("第{0}张卡第{1}个获取输出信号失败 ---- ", m_nCardIndex, nIndex));
            //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个获取输出信号失败 ---- ", m_nCardIndex, nIndex));
            return false;
        }

        /// <summary>
        /// 按位输出信号
        /// </summary>
        /// <param name="nIndex">点位号</param>
        /// <param name="bBit">True False</param>
        /// <returns></returns>
        public override void WriteOut(int nCardN0, int nIndex, bool bBit)
        {
            short rtn = 0;
            rtn += GtsBase.GT_SetDoBit((short)m_nCardIndex, GtsBase.MC_GPO, (short)nIndex, (short)(bBit ? 0 : 1));// 卡号 12通用输出  输出IO索引 1高电平 0 点电平
            if (0 != rtn)
            {
                //MessageBox.Show(string.Format("第{0}张卡第{1}个输出信号失败原因{2} ---- ", m_nCardIndex, nIndex, rtn));
                //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个输出信号失败原因{2}---- ", m_nCardIndex, nIndex, rtn));
            }
        }

        /// <summary>
        /// 开启使能
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override void ServoOn(int nAxisNo)
        {
            short rtn = 0;
            rtn += GtsBase.GT_ClrSts((short)m_nCardIndex, (short)nAxisNo, 8);//清除报警
            rtn += GtsBase.GT_AxisOn((short)m_nCardIndex, (short)nAxisNo);//开启使能
            if (0 != rtn)
            {
                //MessageBox.Show(string.Format("第{0}张卡第{1}个轴开始使能失败原因{2} ---- ", m_nCardIndex, nAxisNo, rtn));
                //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴开始使能失败原因{2} ---- ", m_nCardIndex, nAxisNo, rtn));
            }
        }

        /// <summary>
        /// 关闭使能
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override void ServoOff(int nAxisNo)
        {
            short rtn = 0;
            rtn += GtsBase.GT_AxisOff((short)m_nCardIndex, (short)nAxisNo);//关闭使能
            if (0 != rtn)//关闭使能
            {
                //MessageBox.Show(string.Format("第{0}张卡第{1}个轴关闭使能失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
                //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴关闭使能失败原因{2} ---- ", m_nCardIndex, nAxisNo, rtn));
            }
        }

        /// <summary>
        /// 轴清除报警
        /// </summary>
        /// <param name="nAxisNo"></param>
        /// <returns></returns>
        public override void ClearAxisAlarm(int nAxisNo)
        {
            short rtn = 0;
            rtn += GtsBase.GT_ClrSts((short)m_nCardIndex, (short)nAxisNo, 8);//清除报警
            if (0 != rtn)
            {
               // MessageBox.Show(string.Format("第{0}张卡第{1}个轴清除报警失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
               //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴清除报警失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            }
        }

        /// <summary>
        /// 位置清零
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override void SetPosZero(int nAxisNo)
        {
            short rtn = 0;
            rtn += GtsBase.GT_ZeroPos((short)m_nCardIndex, (short)nAxisNo, 1);// 卡号 轴号 需要清零的轴数（1）
            if (0 != rtn)
            {
                //MessageBox.Show(string.Format("第{0}张卡第{1}个轴位置清零失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
                //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴位置清零失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            }
        }

        /// <summary>
        /// 轴正常停止
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override void StopAxis(int nAxisNo)
        {
            short rtn = 0;
            rtn += GtsBase.GT_Stop((short)m_nCardIndex, 1 << (nAxisNo - 1), 0);//卡号 轴号 停止方式 0平滑停止 1急停
            if (0 != rtn)
            {
                //MessageBox.Show(string.Format("第{0}张卡第{1}个轴正常停止原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
                //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴正常停止失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            }
        }

        /// <summary>
        /// 轴紧急停止
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override void EmgAxis(int nAxisNo)
        {
            short rtn = 0;
            rtn += GtsBase.GT_Stop((short)m_nCardIndex, 1 << (nAxisNo - 1), 1);//卡号  0代表1轴 1代表2轴  轴号 停止方式 0平滑停止 1急停
            if (0 != rtn)
            {
                //MessageBox.Show(string.Format("第{0}张卡第{1}个轴紧急停止原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
                //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴位置紧急停止原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            }
        }

        /// <summary>
        /// 获取轴当前编码器位置
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override double GetAxisActPos(int nAxisNo)
        {
            short rtn = 0;
            double pos = 0;
            uint clk = 0;
            rtn += GtsBase.GT_GetEncPos((short)m_nCardIndex, (short)nAxisNo, out pos, 1, out clk);//读取编码器位置 卡号 轴号 位置 时钟 
            if (0 == rtn)
            {
                return pos / SystemCfg.AxisCfg[nAxisNo].PluseRatio;
            }
            //MessageBox.Show(string.Format("第{0}张卡第{1}个轴获取编码器位置失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴获取编码器位置失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            return 0;
        }

        /// <summary>
        /// 获取轴当前规划位置
        /// </summary>
        /// <param name="nAxisNo"></param>
        /// <returns></returns>
        public override double GetAxisPrfPos(int nAxisNo)
        {
            short rtn = 0;
            double pos = 0;
            uint clk = 0;
            rtn += GtsBase.GT_GetAxisPrfPos((short)m_nCardIndex, (short)nAxisNo, out pos, 1, out clk);//读取规划位置 卡号 轴号 位置 时钟
            if (0 == rtn)
            {
                return pos / SystemCfg.AxisCfg[nAxisNo].PluseRatio;
            }
            //MessageBox.Show(string.Format("第{0}张卡第{1}个轴获取规划位置失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴获取规划位置失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            return 0;
        }

        /// <summary>
        /// 获取轴使能信号
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override bool GetAxisSeverOn(int nAxisNo)
        {
            short rtn = 0;
            int sts = 0;
            uint clk = 0;
            rtn = GtsBase.GT_GetSts((short)m_nCardIndex, (short)nAxisNo, out sts, 1, out clk);
            if (0 == rtn)
            {
                return 0 != (sts & 0x200);//伺服已上使能
            }
            //MessageBox.Show(string.Format("第{0}张卡第{1}个轴获取使能失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴获取使能失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            return false;
        }

        /// <summary>
        /// 获取轴报警信号
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override bool GetAxisAlarm(int nAxisNo)
        {
            short rtn = 0;
            int sts = 0;
            uint clk = 0;
            rtn = GtsBase.GT_GetSts((short)m_nCardIndex, (short)nAxisNo, out sts, 1, out clk);
            if (0 == rtn)
            {
                return 0 != (sts & 0x2);//伺服报警中
            }
            //MessageBox.Show(string.Format("第{0}张卡第{1}个轴获取报警失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴获取报警失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            return false;
        }

        /// <summary>
        /// 获取轴忙信号
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override bool GetAxisBusy(int nAxisNo)
        {
            short rtn = 0;
            int sts = 0;
            uint clk = 0;
            rtn = GtsBase.GT_GetSts((short)m_nCardIndex, (short)nAxisNo, out sts, 1, out clk);
            if (0 == rtn)
            {
                return 0 != (sts & 0x400);//规划器正在运行 轴Busy
            }
            //MessageBox.Show(string.Format("第{0}张卡第{1}个轴获取Busy失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴获取Busy失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            return false;
        }

        /// <summary>
        /// 获取轴到位完成信号
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override bool GetAxisDone(int nAxisNo)
        {
            short rtn = 0;
            int sts = 0;
            uint clk = 0;
            rtn += GtsBase.GT_SetAxisBand((short)m_nCardIndex, (short)nAxisNo, 20, 5);//设置轴到位误差
            rtn += GtsBase.GT_GetSts((short)m_nCardIndex, (short)nAxisNo, out sts, 1, out clk);
            if (0 == rtn)
            {
                //轴上使能
                if ((sts & 0X200) != 0)
                {
                    //伺服已停止 轴不Busy
                    if ((sts & 0x400) == 0)
                    {
                        // 正限位未触发
                        //if ((sts & 0x20) == 0)
                        //{
                        //    //负限位未触发
                        //    if ((sts & 0x40) == 0)
                        //    {
                                //伺服未报警
                                if ((sts & 0x2) == 0)
                                {
                                    //电机到位标志
                                    if ((sts & 0x800) != 0)
                                    {
                                        return true;
                                    }
                                }
                        //    }
                        //}
                    }
                }
            }
            //MessageBox.Show(string.Format("第{0}张卡第{1}个轴获取到位信号失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴获取到位信号失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            return false;
        }

        /// <summary>
        /// 获取轴运动准备信号
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <returns></returns>
        public override bool GetAxisReady(int nAxisNo)
        {
            short rtn = 0;
            int sts = 0;
            uint clk = 0;
            rtn += GtsBase.GT_GetSts((short)m_nCardIndex, (short)nAxisNo, out sts, 1, out clk);
            if (0 == rtn)
            {
                //伺服已上使能
                if ((sts & 0X200) != 0)
                {
                    //伺服已停止 轴不Busy
                    if ((sts & 0x400) == 0)
                    {
                        //伺服未报警
                        if ((sts & 0x2) == 0)
                        {
                            return true;//电机运动准备好
                        }
                    }
                }
            }
            //MessageBox.Show(string.Format("第{0}张卡第{1}个轴获取运动准备失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴获取运动准备失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            return false;

        }

        /// <summary>
        /// 获取轴原点信号
        /// </summary>
        /// <param name="nIndex">轴号</param>
        /// <returns></returns>
        public override bool GetAxisHome(int nIndex)
        {
            int nData = 0;
            if (0 == GtsBase.GT_GetDi((short)m_nCardIndex, GtsBase.MC_HOME, out nData))//卡号 4 通用输入
            {
                return 0 == (nData & (1 << (nIndex - 1)));//原点信号触发   显示常开
            }
            //MessageBox.Show(string.Format("第{0}张卡第{1}个轴获取原点信号失败原因{2}---- ", m_nCardIndex, nIndex));
            //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴获取原点信号失败原因{2}---- ", m_nCardIndex, nIndex));
            return false;
        }

        /// <summary>
        /// 获取轴正限位信号
        /// </summary>
        /// <param name="nIndex">轴号</param>
        /// <returns></returns>
        public override bool GetPosLimit(int nIndex)
        {
            int nData = 0;
            if (0 == GtsBase.GT_GetDi((short)m_nCardIndex, GtsBase.MC_LIMIT_POSITIVE, out nData))//卡号 4 通用输入
            {
                return 0 != (nData & (1 << (nIndex - 1)));//正限位信号未触发  显示常开

            }
            //MessageBox.Show(string.Format("第{0}张卡第{1}个轴获取正限位信号失败原因{2}---- ", m_nCardIndex, nIndex));
            //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴获取正限位信号失败原因{2}---- ", m_nCardIndex, nIndex));
            return false;
        }

        /// <summary>
        /// 获取轴负限位信号
        /// </summary>
        /// <param name="nIndex">轴号</param>
        /// <returns></returns>
        public override bool GetNegLimit(int nIndex)
        {
            int nData = 0;
            if (0 == GtsBase.GT_GetDi((short)m_nCardIndex, GtsBase.MC_LIMIT_NEGATIVE, out nData))//卡号 4 通用输入
            {
                return 0 != (nData & (1 << (nIndex - 1)));//负限位信号未触发 显示常开
            }
            //MessageBox.Show(string.Format("第{0}张卡第{1}个轴获取负限位信号失败原因{2}---- ", m_nCardIndex, nIndex));
            //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴获取负限位信号失败原因{2}---- ", m_nCardIndex, nIndex));
            return false;

        }

        /// <summary>
        /// 绝对运动
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <param name="nPos">目标位置</param>
        /// <param name="nSpeed">速度</param>
        /// <returns></returns>
        public override void AbsMove(int nAxisNo, double Pos, double Speed)
        {
            short rtn = 0;
            GtsBase.GT_SetAxisBand((short)m_nCardIndex, (short)nAxisNo, 20, 5);//设置轴到位误差 卡号 轴号 误差带大小 误差带保存时间
            GtsBase.TTrapPrm trap = new GtsBase.TTrapPrm();//定位参数
            double acc = SystemCfg.AxisCfg[nAxisNo].Acc;//加速时间
            double dec = SystemCfg.AxisCfg[nAxisNo].Dec;//减速时间
            double start = SystemCfg.AxisCfg[nAxisNo].StartSpeed;//起始速度
            trap.acc = acc;//加速度
            trap.dec = dec;//减速度
            trap.velStart = start;//起跳速度
            trap.smoothTime = 10;//平滑时间
            double nPos =  Convert.ToInt32( Pos * SystemCfg.AxisCfg[nAxisNo].PluseRatio);
            double nSpeed = Speed ;
            rtn += GtsBase.GT_ClrSts((short)m_nCardIndex, (short)nAxisNo, 8);//消除报警 卡号 轴号 8个轴
            rtn += GtsBase.GT_PrfTrap((short)m_nCardIndex, (short)nAxisNo);//设置点位运动模式 卡号 轴号
            rtn += GtsBase.GT_SetTrapPrm((short)m_nCardIndex, (short)nAxisNo, ref trap);//设置点位运动模式下的运动参数 卡号 轴号 参数
            rtn += GtsBase.GT_SetVel((short)m_nCardIndex, (short)nAxisNo, (double)nSpeed);//设置目标速度 卡号 轴号 速度
            rtn += GtsBase.GT_SetPos((short)m_nCardIndex, (short)nAxisNo, (int)nPos);//设置目标位置 卡号 轴号 位置
            rtn += GtsBase.GT_Update((short)m_nCardIndex, 1 << (nAxisNo - 1));  //启动点位运动或Jog运动  卡号 轴号 0代表1轴 1代表2轴
            if (0 != rtn)
            {
                //MessageBox.Show(string.Format("第{0}张卡第{1}个轴绝对运动失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
                //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴绝对运动失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            }
        }

        /// <summary>
        /// 相对运行
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <param name="nPos">目标位置</param>
        /// <param name="nSpeed">速度</param>
        /// <returns></returns>
        public override void RelMove(int nAxisNo, double Pos, double Speed)
        {

            short rtn = 0;
            GtsBase.GT_SetAxisBand((short)m_nCardIndex, (short)nAxisNo, 20, 5);//设置轴到位误差 卡号 轴号 误差带大小 误差带保存时间
            GtsBase.TTrapPrm trap = new GtsBase.TTrapPrm();//定位参数
            double acc = SystemCfg.AxisCfg[nAxisNo].Acc;//加速时间
            double dec = SystemCfg.AxisCfg[nAxisNo].Dec;//减速时间
            double start = SystemCfg.AxisCfg[nAxisNo].StartSpeed;//起始速度
            trap.acc = acc;//加速度
            trap.dec = acc;//减速度
            trap.velStart = start;//起跳速度
            trap.smoothTime = 10;//平滑时间
            double nPos = Pos * SystemCfg.AxisCfg[nAxisNo].PluseRatio;
            double nSpeed = Speed;
            int extPos = 0;
            rtn += GtsBase.GT_ClrSts((short)m_nCardIndex, (short)nAxisNo, 8);//消除报警
            rtn += GtsBase.GT_PrfTrap((short)m_nCardIndex, (short)nAxisNo);//设置点位运动模式 卡号 轴号
            rtn += GtsBase.GT_SetTrapPrm((short)m_nCardIndex, (short)nAxisNo, ref trap);//设置点位运动模式下的运动参数 卡号 轴号
            rtn += GtsBase.GT_SetVel((short)m_nCardIndex, (short)nAxisNo, (double)nSpeed);//设置目标速度 卡号 轴号 速度
            rtn += GtsBase.GT_GetPos((short)m_nCardIndex, (short)nAxisNo, out extPos);//读取目标位置 卡号 轴号 位置
            rtn += GtsBase.GT_SetPos((short)m_nCardIndex, (short)nAxisNo, (int)extPos + (int)nPos);//设置目标位置 卡号 轴号 位置
            rtn += GtsBase.GT_Update((short)m_nCardIndex, 1 << (nAxisNo - 1));//启动运动 
            if (0 != rtn)
            {
                //MessageBox.Show(string.Format("第{0}张卡第{1}个轴相对运动失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
                //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴相对运动失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            }
        }

        /// <summary>
        /// Jog运动模式
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <param name="nSpeed">速度</param>
        /// <param name="bPositive">方向</param>
        /// <returns></returns>
        public override void JogMove(int nAxisNo, double Speed, bool MovDir)
        {

            short rtn = 0;
            GtsBase.TJogPrm trap = new GtsBase.TJogPrm();          
            double acc = SystemCfg.AxisCfg[nAxisNo].Acc;//加速时间
            double dec = SystemCfg.AxisCfg[nAxisNo].Dec;//减速时间
            double start = SystemCfg.AxisCfg[nAxisNo].StartSpeed;//起始速度
           double  smoothtime = SystemCfg.AxisCfg[nAxisNo].SmoothTime;//平滑时间
            trap.acc = 0.1;//Jog加速度
            trap.dec = 0.1;//Jog减速度
            trap.smooth = 0;//平滑时间
            double nSpeed = Speed;
            rtn += GtsBase.GT_ClrSts((short)m_nCardIndex, (short)nAxisNo, 8);//消除报警
            rtn += GtsBase.GT_PrfJog((short)m_nCardIndex, (short)nAxisNo);//设置指定轴为Jog运动模式
      //    rtn += GtsBase.GT_GetJogPrm((short)m_nCardIndex, (short)nAxisNo, out trap);//读取Jog运动模式下的运动参数
            rtn += GtsBase.GT_SetJogPrm((short)m_nCardIndex, (short)nAxisNo, ref trap);//设置Jog运动模式下的运动参数
            rtn += GtsBase.GT_SetVel((short)m_nCardIndex, (short)nAxisNo, MovDir ? (double)nSpeed : (double)-nSpeed);//设置速度 卡号 轴号 速度
            rtn += GtsBase.GT_Update((short)m_nCardIndex, 1 << (nAxisNo - 1));//启动点位运动
             if (0 != rtn)
            {
                //MessageBox.Show(string.Format("第{0}张卡第{1}个轴Jog运动失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
                //LogView.GetInstance().ShowLog(LogView.LogType.Error, string.Format("第{0}张卡第{1}个轴Jog运动失败原因{2}---- ", m_nCardIndex, nAxisNo, rtn));
            }
        }

        /// <summary>
        /// 回原点
        /// </summary>
        /// <param name="nAxisNo">轴号</param>
        /// <param name="MoveDir">方向 0 是负方向 1是正方向</param>
        public override void HomeMove(int nAxisNo, int MoveDir, uint HomeMode)
        {
            // nAxisNo += 1;
            uint axisMark = (uint)1 << (nAxisNo - 1);
            _homeMutex.WaitOne();
            if (0 != (_isHomeNow & axisMark))
            {
                _homeMutex.ReleaseMutex();
               // return false;
            }
            _isHomeNow |= axisMark;
            _isHomeErr &= ~axisMark;
            _homeMutex.ReleaseMutex();
            Task.Run(delegate ()
            {//负极限归原点
                short sRtn = 0;
                int goPosVel;
                int lastGoPos;
                GtsBase.GT_ClrSts((short)m_nCardIndex, (short)nAxisNo, 1);
                GtsBase.GT_AxisOn((short)m_nCardIndex, (short)nAxisNo);
                Func<bool> isNegLimit = delegate ()
                {
                    int negLimit = 0;
                    GtsBase.GT_GetDi((short)m_nCardIndex, GtsBase.MC_LIMIT_NEGATIVE, out negLimit);
                    return 0 != (negLimit & (1 << (nAxisNo - 1)));
                };
                Action<int> jogToNeg = delegate (int vel)
                {
                    GtsBase.TJogPrm jogPrm = new GtsBase.TJogPrm();
                    int status;
                    uint clk;

                    GtsBase.GT_ClrSts((short)m_nCardIndex, (short)nAxisNo, 1);
                    GtsBase.GT_ZeroPos((short)m_nCardIndex, (short)nAxisNo, 1);
                    GtsBase.GT_PrfJog((short)m_nCardIndex, (short)nAxisNo);
                    GtsBase.GT_GetJogPrm((short)m_nCardIndex, (short)nAxisNo, out jogPrm);
                    jogPrm.acc = 0.1;//Jog加速度
                    jogPrm.dec = 0.1;//Jog减速度
                    GtsBase.GT_SetJogPrm((short)m_nCardIndex, (short)nAxisNo, ref jogPrm);
                    GtsBase.GT_SetVel((short)m_nCardIndex, (short)nAxisNo, vel);
                    GtsBase.GT_Update((short)m_nCardIndex, 1 << (nAxisNo - 1));
                    double encPos = -10000000;
                    double lastEncPos = 0;
                    do
                    {
                        Thread.Sleep(1);
                        GtsBase.GT_GetSts((short)m_nCardIndex, (short)nAxisNo, out status, 1, out clk);
                        lastEncPos = encPos;
                        GtsBase.GT_GetEncPos((short)m_nCardIndex, (short)nAxisNo, out encPos, 1, out clk);
                    } while (0 == (_stopHome & axisMark) && 0 == sRtn && (0 != (status & 0x400) || Math.Abs(lastEncPos - encPos) > 10));
                };
                Action<int, int> ptGo = delegate (int vel, int npos)
                {
                    GtsBase.TTrapPrm trapPrm = new GtsBase.TTrapPrm();
                    int status;
                    uint clk;

                    GtsBase.GT_ClrSts((short)m_nCardIndex, (short)nAxisNo, 1);
                    GtsBase.GT_ZeroPos((short)m_nCardIndex, (short)nAxisNo, 1);
                    GtsBase.GT_PrfTrap((short)m_nCardIndex, (short)nAxisNo);
                    GtsBase.GT_GetTrapPrm((short)m_nCardIndex, (short)nAxisNo, out trapPrm);
                    trapPrm.acc = 0.1;//加速度
                    trapPrm.dec = 0.1;//减速度
                    GtsBase.GT_SetTrapPrm((short)m_nCardIndex, (short)nAxisNo, ref trapPrm);
                    GtsBase.GT_SetVel((short)m_nCardIndex, (short)nAxisNo, vel);
                    GtsBase.GT_SetPos((short)m_nCardIndex, (short)nAxisNo, npos);
                    GtsBase.GT_Update((short)m_nCardIndex, 1 << (nAxisNo - 1));
                    double encPos = -10000000;
                    double lastEncPos = 0;
                    do
                    {
                        Thread.Sleep(1);
                        GtsBase.GT_GetSts((short)m_nCardIndex, (short)nAxisNo, out status, 1, out clk);
                        lastEncPos = encPos;
                        GtsBase.GT_GetEncPos((short)m_nCardIndex, (short)nAxisNo, out encPos, 1, out clk);
                    } while (0 == (_stopHome & axisMark) && 0 == sRtn && (0 != (status & 0x400) || Math.Abs(lastEncPos - encPos) > 10));
                };
                if (0 == sRtn && !isNegLimit() && 0 == sRtn)
                {
                    jogToNeg(-20);
                    while (0 == (_stopHome & axisMark) && 0 == sRtn && !isNegLimit() && 0 == sRtn)
                    {//冲过头，越过负极限
                        ptGo(10, 100);
                    }
                }
                goPosVel = 20;
                lastGoPos = 1024;
                do
                {
                    while (0 == (_stopHome & axisMark) && 0 == sRtn && isNegLimit() && 0 == sRtn)
                    {
                        ptGo(goPosVel, lastGoPos);
                    }
                    if (0 != sRtn || 1 == lastGoPos)
                    {
                        break;
                    }
                    lastGoPos /= 2;

                    while (0 == (_stopHome & axisMark) && 0 == sRtn && !isNegLimit() && 0 == sRtn)
                    {
                        ptGo(goPosVel, -lastGoPos);
                    }
                    lastGoPos /= 2;
                } while (0 == (_stopHome & axisMark));
                GtsBase.GT_ZeroPos((short)m_nCardIndex, (short)nAxisNo, 1);//清零规划位置和实际位置
                ptGo(goPosVel, 2000);
                Thread.Sleep(1000);
                GtsBase.GT_ZeroPos((short)m_nCardIndex, (short)nAxisNo, 1);//清零规划位置和实际位置
                GtsBase.GT_ClrSts((short)m_nCardIndex, (short)nAxisNo, 1);
                _homeMutex.WaitOne();
                _isHomeErr = (0 != sRtn && 0 == (_stopHome & axisMark)) ? (_isHomeErr | axisMark) : (_isHomeErr & ~axisMark);
                _isHomeNow &= ~axisMark;
                _stopHome &= ~axisMark;
                _homeMutex.ReleaseMutex();

            });
          //  return true;
        }

        public override void InitExtIoCard(int CarsNO)
        {
            short rtn = 0;
            ushort nData;
            rtn += GtsBase.GT_OpenExtMdl((short)m_nCardIndex, "gts.dll");
            rtn += GtsBase.GT_ResetExtMdl((short)m_nCardIndex);
            if (CarsNO == 0)
            {
                rtn += GtsBase.GT_LoadExtConfig((short)m_nCardIndex, AppDomain.CurrentDomain.BaseDirectory + "ExtModule.cfg");//加载拓展模块配置文件
            }
            rtn += GtsBase.GT_ClrSts((short)m_nCardIndex, 1, 8);
            rtn += GtsBase.GT_GetExtIoValue((short)m_nCardIndex, (short)CarsNO, out nData);
            m_bEnable = 0 == rtn;
        }

        public override void DeInitExtIoCard(int Card)
        {
            GtsBase.GT_CloseExtMdl((short)m_nCardIndex);
        }

        public override bool ReadExtIn(int CardNo, int nIndex)
        {
            ushort data;
            if (0 == GtsBase.GT_GetExtIoBit((short)m_nCardIndex, (short)(CardNo), (short)(nIndex), out data))
            {
                return 0 == data;
            }
            return false;
        }

        public override bool ReadExtOut(int CardNo, int nIndex)
        {
            ushort nData = 0;
            if (0 == GtsBase.GT_GetExtDoValue((short)m_nCardIndex, (short)(CardNo), out nData))
            {
                //取16位中的某一位  如果是0 低电平 1 高电平
                return 0 == (nData & (1 << (nIndex))); //信号触发
            }
            return false;
        }

        public override void WriteExtOut(int CardNo, int nIndex, bool bBit)
        {
            GtsBase.GT_SetExtIoBit((short)m_nCardIndex, (short)CardNo, (short)(nIndex), (ushort)(bBit ? 0 : 1));
        }
      
        public override bool GetBusState()
        {
            throw new NotImplementedException();
        }

        public override void ClearBusAlarm()
        {
            throw new NotImplementedException();
        }

        public override bool HomeMove1(int nAxisNo, int MoveDir)
        {
            short sRtn = 0;
            GtsBase.THomePrm tHomePrm = new GtsBase.THomePrm(); //回零参数
            GtsBase.THomeStatus pHomeStatus;//使用home回零或home+index回零，若轴停止在home点则需要先移开home点在开启回零。由实际情况确认。
            sRtn = GtsBase.GT_ClrSts((short)m_nCardIndex, (short)nAxisNo, 8);//回零前先清除状态
            sRtn = GtsBase.GT_ZeroPos((short)m_nCardIndex, (short)nAxisNo, 1);//清除规划和实际位置
            sRtn = GtsBase.GT_GetHomePrm((short)m_nCardIndex, (short)nAxisNo, out tHomePrm);//读取回零参数             
                                                                                            //  tHomePrm.mode = GtsBase.HOME_MODE_LIMIT;//限位回原点 不需要原点
         //   tHomePrm.mode = GtsBase.HOME_MODE_LIMIT_HOME;//限位+Home回原点 先去限位再回原点感应器        
            tHomePrm.mode = GtsBase.HOME_MODE_HOME;//限位+Home回原点 先去限位再回原点感应器        
            tHomePrm.searchHomeDistance = 0;    //搜索Home距离，0表示最大距离搜索
            tHomePrm.searchIndexDistance = 0;   //搜索index距离，0表示最大距离搜索
            tHomePrm.moveDir = -1;       //回零方向 1为正 -1为负
            tHomePrm.indexDir = 1;           //搜索index方向 1为正 -1为负
            tHomePrm.velHigh = 20;              //寻找限位速度
            tHomePrm.velLow = 5;                //寻找home、index速度
            tHomePrm.smoothTime = 10;           //平滑时间，运动加减速平滑
            tHomePrm.acc = 1;               //加速度
            tHomePrm.dec = 1;               //减速度
            tHomePrm.escapeStep = 10000;    //限位回零后方式时第一次找到限位反向移动距离
            tHomePrm.homeOffset = 0;        //原点偏移 = 0
            sRtn = GtsBase.GT_GoHome((short)m_nCardIndex, (short)nAxisNo, ref tHomePrm);//启动SmartHome回原点
            do
            {
                sRtn = GtsBase.GT_GetHomeStatus((short)m_nCardIndex, (short)nAxisNo, out pHomeStatus);//获取回原点状态
            }
            while (pHomeStatus.run == 1 && pHomeStatus.stage != 100); // 等待搜索原点停止run和stage来判断是否回零完成。
                                                                      // run 回零状态：0已停止运动 1正在运动
                                                                      // stage 0-100 对应宏定义，请查阅固高手册可以查询回零过程，stage = 100表示回零成功。
            Thread.Sleep(1000);     //等待电机完全停止，时间由电机调试效果确定也可采用到位判断
            sRtn += GtsBase.GT_ZeroPos((short)m_nCardIndex, (short)nAxisNo, 1);  //回零完成手动清零
        
            if (sRtn == 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public override void OpenCmd(int cardNum, ushort channel, uint dir)
        {
          
        }

        public override void CloseCmd(int cardNum, ushort channel)
        {
          
        }

        public override void SetCmdData(int cardNum, ushort channel, double[] data)
        {
           
        }

        public override int GetCmdFIFOCount(int cardNum, ushort channel)
        {
            return 0;
        }

        public override void SetCmdDO(int cardNum, ushort channel)
        {
          
        }

        public override void CloseCmdDO(int cardNum, ushort channel)
        {
         
        }

        public override void ResetCmd(int cardNum, ushort channel)
        {
          
        }

        public override bool HomeOK(int nAxisNo)
        {
            throw new NotImplementedException();
        }
    }
}
